﻿/*
Typps HTML Editor for ASP.NET
FULL EDITION

Copyright (c) 2009 Alessandro Zifiglio, http://www.Typps.com
EMail: alessandro@Typps.com

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
Typps.ImagePicker = function (element) {
    Typps.ImagePicker.initializeBase(this, [element]);
    this._updatePanelProgressId = null;
    this._mediaFrameId = null;
    this._callbacks = null;
    this._display = null;
    this._shaderColor = '#e2e2e2';
    this._shaderOpacity = 20;
    this._className = null;
    this._timeout = 0;
    this._imageUploadingMessage = null;
    this._cancelButtonDelegate = null;
    this._okButtonDelegate = null;
    this._targetControlId = null;
    this._targetControlDelegate = null;
    this._popperId = null;
    this._targetControlActivationOn = null;
    this._imageBrowserEnabled = false;
    this._imageUploadEnabled = true;
    this._authority = null;
    this._httpHandlerUrl = null;
    this._loadFailureUrl = null;
    this._thumbnailWidth = 100;
    this._displayImageDesignerUrlField = null;
    this._displayImageDesignerAttributes = null;
    this._uniqueId = null;
    this._targetImageElementId = null;
    this._document = document;
}
Typps.ImagePicker.prototype = {
    get_uniqueId: function () {
        return this._uniqueId;
    },
    set_uniqueId: function (value) {
        this._uniqueId = value;
    },
    get_updatePanelProgressId: function () {
        return this._updatePanelProgressId;
    },
    set_updatePanelProgressId: function (value) {
        this._updatePanelProgressId = value;
    },
    get_mediaFrameId: function () {
        return this._mediaFrameId;
    },
    set_mediaFrameId: function (value) {
        this._mediaFrameId = value;
    },
    get_timeout: function () {
        return this._timeout;
    },
    set_timeout: function (value) {
        this._timeout = value;
    },
    get_targetControlActivationOn: function () {
        return (this._targetControlActivationOn == null) ? 'click' : this._targetControlActivationOn;
    },
    set_targetControlActivationOn: function (value) {
        this._targetControlActivationOn = value;
    },
    get_imageUploadingMessage: function () {
        return this._imageUploadingMessage;
    },
    set_imageUploadingMessage: function (value) {
        this._imageUploadingMessage = value;
    },
    get_imageBrowserEnabled: function () {
        return this._imageBrowserEnabled;
    },
    set_imageBrowserEnabled: function (value) {
        this._imageBrowserEnabled = value;
    },
    get_imageUploadEnabled: function () {
        return this._imageUploadEnabled;
    },
    set_imageUploadEnabled: function (value) {
        this._imageUploadEnabled = value;
    },
    get_callbacks: function () {
        return this._callbacks;
    },
    set_callbacks: function (value) {
        this._callbacks = value;
    },
    get_targetControlId: function () {
        return this._targetControlId;
    },
    set_targetControlId: function (value) {
        this._targetControlId = value;
    },
    get_targetImageElementId: function () {
        return this._targetImageElementId;
    },
    set_targetImageElementId: function (value) {
        this._targetImageElementId = value;
    },
    get_display: function () {
        return (this._display == null) ? false : this._display;
    },
    set_display: function (value) {
        this._display = value;
    },
    get_className: function () {
        return this._className;
    },
    set_className: function (value) {
        this._className = value;
    },
    get_shaderColor: function () {
        return this._shaderColor;
    },
    set_shaderColor: function (value) {
        this._shaderColor = value;
    },
    get_shaderOpacity: function () {
        return this._shaderOpacity;
    },
    set_shaderOpacity: function (value) {
        this._shaderOpacity = value;
    },
    get_formElementId: function () {
        return this._formElementId;
    },
    set_formElementId: function (value) {
        this._formElementId = value;
    },
    get_postbackAllFormData: function () {
        return this._postbackAllFormData;
    },
    set_postbackAllFormData: function (value) {
        this._postbackAllFormData = value;
    },
    get_authority: function () {
        return this._authority;
    },
    set_authority: function (value) {
        this._authority = value;
    },
    get_httpHandlerUrl: function () {
        return this._httpHandlerUrl;
    },
    set_httpHandlerUrl: function (value) {
        this._httpHandlerUrl = value;
    },
    get_loadFailureUrl: function () {
        return this._loadFailureUrl;
    },
    set_loadFailureUrl: function (value) {
        this._loadFailureUrl = value;
    },
    get_thumbnailWidth: function () {
        return this._thumbnailWidth;
    },
    set_thumbnailWidth: function (value) {
        this._thumbnailWidth = value;
    },
    get_displayImageDesignerUrlField: function () {
        return this._displayImageDesignerUrlField;
    },
    set_displayImageDesignerUrlField: function (value) {
        this._displayImageDesignerUrlField = value;
    },
    get_displayImageDesignerAttributes: function () {
        return this._displayImageDesignerAttributes;
    },
    set_displayImageDesignerAttributes: function (value) {
        this._displayImageDesignerAttributes = value;
    },
    get_document: function () {
        return this._document;
    },
    set_document: function (value) {
        this._document = value;
    },
    add_targetControlClick: function (handler) {
        this.get_events().addHandler('targetcontrolclick', handler);
    },
    remove_targetControlClick: function (handler) {
        this.get_events().removeHandler('targetcontrolclick', handler);
    },
    add_thumbnailLoaded: function (handler) {
        this.get_events().addHandler('thumbnailloaded', handler);
    },
    remove_thumbnailLoaded: function (handler) {
        this.get_events().removeHandler('thumbnailloaded', handler);
    },
    add_thumbnailClicked: function (handler) {
        this.get_events().addHandler('thumbnailclicked', handler);
    },
    remove_thumbnailClicked: function (handler) {
        this.get_events().removeHandler('thumbnailclicked', handler);
    },
    add_cancelButton: function (handler) {
        this.get_events().addHandler('cancel', handler);
    },
    remove_cancelButton: function (handler) {
        this.get_events().removeHandler('cancel', handler);
    },
    add_okButton: function (handler) {
        this.get_events().addHandler('ok', handler);
    },
    remove_okButton: function (handler) {
        this.get_events().removeHandler('ok', handler);
    },
    add_beginWebRequest: function (handler) {
        this.get_events().addHandler('beginWebRequest', handler);
    },
    remove_beginWebRequest: function (handler) {
        this.get_events().removeHandler('beginWebRequest', handler);
    },
    add_endWebRequest: function (handler) {
        this.get_events().addHandler('endWebRequest', handler);
    },
    remove_endWebRequest: function (handler) {
        this.get_events().removeHandler('endWebRequest', handler);
    },
    add_popperAction: function (handler) {
        this.get_events().addHandler('popper', handler);
    },
    remove_popperAction: function (handler) {
        this.get_events().removeHandler('popper', handler);
    },
    // Release resources before control is disposed.
    dispose: function () {
        if (this._okButtonDelegate) {
            this._imageDesignerWindow.remove_okButton(this._okButtonDelegate);
            delete this._okButtonDelegate;
        }
        if (this._cancelButtonDelegate) {
            this._imageDesignerWindow.remove_cancelButton(this._cancelButtonDelegate);
            delete this._cancelButtonDelegate;
        }
        if (this._targetControlDelegate) {
            if (this._targetControlId != null) {
                var targetControl = $get(this._targetControlId);
                if (targetControl != null)
                    Sys.UI.DomEvent.removeHandler(targetControl, this._targetControlActivationOn, this._targetControlDelegate);
            }
        }
        delete this._targetControlDelegate;
        if (this._beginRequestHandlerDelegate) { delete this._beginRequestHandlerDelegate; }
        if (this._beginRequestHandlerDelegate) { delete this._endRequestHandlerDelegate; }

        //insert image designer
        if (this._btnBrowseDelegate) {
            Sys.UI.DomEvent.removeHandler($get(this._imgDesignerId + '_btnbrowse'), 'click', this._btnBrowseDelegate);
            delete this._btnBrowseDelegate;
        }
        if (this._btnImgUploadDelegate) {
            Sys.UI.DomEvent.removeHandler($get(this._imgDesignerId + '_btnimgupload'), 'click', this._btnImgUploadDelegate);
            delete this._btnImgUploadDelegate;
        }

        if (this._btnImgBrowserOkDelegate)
            delete this._btnImgBrowserOkDelegate;
        if (this._btnImgBrowserCancelDelegate)
            delete this._btnImgBrowserCancelDelegate;
        if (this._btnImgUploaderOkDelegate)
            delete this._btnImgUploaderOkDelegate;
        if (this._btnImgUploaderCancelDelegate)
            delete this._btnImgUploaderCancelDelegate;
        if (this._iframeImageUploadDelegate) {
            var iframe = $get(this._imgUploaderId + '_frame');
            Sys.UI.DomEvent.removeHandler(iframe, 'load', this._iframeImageUploadDelegate);
            delete this._iframeImageUploadDelegate;
        }

        this._disposeTreeView();
        if (this._imageDesignerWindow) {
            this._imageDesignerWindow.dispose();
            delete this._imageDesignerWindow;
        }
        if (this._imageBrowserWindow) {
            this._imageBrowserWindow.dispose();
            delete this._imageBrowserWindow;
        }
        if (this._imageUploaderWindow) {
            this._imageUploaderWindow.dispose();
            delete this._imageUploaderWindow;
        }
        Typps.ImagePicker.callBaseMethod(this, 'dispose');
    },
    _disposeTreeView: function () {
        if (this._toggleTreeViewStateDelegate) {
            var treeview = $get(this.get_containerId + '_treeview');
            var num1 = 0;
            if (this._toggleTreeViewStateDelegate) {
                var length = this._rootElements.length - 1;
                //when deleting do it in reverse order or
                //the position of the list changes.
                for (num1 = length; num1 >= 0; num1--) {
                    var span = this._rootElements[num1];
                    if (this._toggleTreeViewStateDelegate != null)
                        Sys.UI.DomEvent.removeHandler(span, 'click', this._toggleTreeViewStateDelegate);
                    Array.remove(this._rootElements, span);
                }
                delete this._toggleTreeViewStateDelegate;
                this._toggleTreeViewStateDelegate = null;
            }

            if (this._leafNodeClickDelegate) {
                length = this._leafElements.length - 1;
                //when deleting do it in reverse order or
                //the position of the list changes.
                for (num1 = length; num1 >= 0; num1--) {
                    span = this._leafElements[num1];
                    if (this._leafNodeClickDelegate)
                        Sys.UI.DomEvent.removeHandler(span, 'click', this._leafNodeClickDelegate);
                    Array.remove(this._leafElements, span);
                }
                delete this._leafNodeClickDelegate;
                this._leafNodeClickDelegate = null;
            }
            var thumbnail = $get(this._imgBrowserId + '_preview_img');
            if (thumbnail != null) {
                if (this._thumbnailLoadedDelegate)
                    Sys.UI.DomEvent.removeHandler(thumbnail, 'load', this._thumbnailLoadedDelegate);

                if (this._thumbnailOnErrorDelegate)
                    thumbnail.onerror = null;
            }
            delete this._thumbnailClickDelegate;
            this._thumbnailClickDelegate = null;
            delete this._thumbnailLoadedDelegate;
            this._thumbnailLoadedDelegate = null;
            delete this._thumbnailOnErrorDelegate;
            this._thumbnailOnErrorDelegate = null;
            if (treeview != null)
                treeview.parentNode.removeChild(treeview);
        }
    },
    initialize: function () {
        Typps.ImagePicker.callBaseMethod(this, 'initialize');
        this._isIE = (Sys.Browser.agent == Sys.Browser.InternetExplorer);
        this._isFF = (Sys.Browser.agent == Sys.Browser.Firefox);
        this._isOpera = (Sys.Browser.agent == Sys.Browser.Opera);
        this._isWebKit = (Sys.Browser.agent == Sys.Browser.WebKit);
        this._btnBrowseDelegate = null;
        this._btnImgUploadDelegate = null;
        this._btnImgOkDelegate = null;
        this._btnImgCancelDelegate = null;
        this._toggleTreeViewStateDelegate = null;
        this._leafNodeClickDelegate = null;
        this._thumbnailClickDelegate = null;
        this._thumbnailLoadedDelegate = null;
        this._thumbnailOnErrorDelegate = null;
        this._onMediaFrameCloseDelegate = null;
        this._onMediaItemDisplayDelegate = null;
        this._btnImgBrowserOkDelegate = null;
        this._btnImgBrowserCancelDelegate = null;
        this._btnImgUploaderOkDelegate = null;
        this._btnImgUploaderDelegate = null;
        this._btnImgUploaderOkDelegate = null;
        this._btnImgUploaderCancelDelegate = null;
        this._iframeImageUploadDelegate = null;
        this._beginRequestHandlerDelegate = null;
        this._endRequestHandlerDelegate = null;
        this._abortRequestHandlerDelegate = null;

        this._imageBrowserContent = null;
        this._imageUploadContent = null;
        this._imageBrowserWindow = null;
        this._imageUploaderWindow = null;
        this._imageDesignerWindow = null;
        this._loadingStatus = null;
        this._targetImage = null; //needed by editor in case were editing

        this._form = Typps.Utility.getForm(this._formElementId);

        this._imgBrowserId = this.get_id() + '_imagebrowser';
        this._imgDesignerId = this.get_id() + '_imagedesigner';
        this._imgUploaderId = this.get_id() + '_fileupload';

        this._updatePanelProgress = null;
        this._mediaFrame = null;
        this._rootElements = [];
        this._leafElements = [];
        if (this._targetControlId != null) {
            var targetControl = $get(this._targetControlId);
            if (targetControl != null) {
                if (this._targetControlDelegate === null) {
                    this._targetControlDelegate = Function.createDelegate(this, this._targetControlHandler);
                }
                Sys.UI.DomEvent.addHandler(targetControl, this._targetControlActivationOn, this._targetControlDelegate);
            }
        }
        if (this._updatePanelProgress === null)
            this._updatePanelProgress = $find(this._updatePanelProgressId);
        if (this._abortRequestHandlerDelegate === null)
            this._abortRequestHandlerDelegate = Function.createDelegate(this, this._abortRequestHandler);
        if (this._abortRequestHandlerDelegate === null && this._updatePanelProgress != null)
            this._updatePanelProgress.add_abortRequest(this._abortRequestHandlerDelegate);
        this._ensureTargetImage();
    },
    _ensureTargetImage: function () {
        if (!Typps.Utility.isNullOrEmpty(this._targetImageElementId))
            this._targetImage = $get(this._targetImageElementId);
    },
    _abortRequestHandler: function (args) { },
    _initializeRequest: function (img) {
        this._targetImage = img;
        this._imgDesignerInitCallback();
    },
    initializeRequest: function () {
        this._imgDesignerInitCallback();
    },
    _createImageUploader: function (markup) {
        var container = document.createElement('div');
        var imageUploadContent = Typps.Utility.getAdjacentHTML(markup, container).firstChild;
        this._imageUploaderWindow = this._createModalPopup(imageUploadContent, this._imgUploaderId, true);
        if (this._btnImgUploaderOkDelegate === null) {
            this._btnImgUploaderOkDelegate = Function.createDelegate(this, this._btnImgUploaderOkHandler);
        }
        if (this._btnImgUploaderCancelDelegate === null) {
            this._btnImgUploaderCancelDelegate = Function.createDelegate(this, this._btnImgUploaderCancelHandler);
        }
        this._imageUploaderWindow.add_okButton(this._btnImgUploaderOkDelegate);
        this._imageUploaderWindow.add_cancelButton(this._btnImgUploaderCancelDelegate);
    },
    _createModalPopup: function (content, id, makeFormChild) {
        var ok = id + '_btnok';
        var cancel = id + '_btncancel';
        var popup = $create(Typps.ModalPopup,
            { id: id, display: true, content: content, title: content.title, isModal: true, className: this._className, shaderColor: this._shaderColor, shaderOpacity: this._shaderOpacity, okButtonId: ok, cancelButtonId: cancel, makeFormChild: makeFormChild, formElementId: this._formElementId },
            null, null, null);

        content.removeAttribute('title');
        return popup;
    },
    _targetControlHandler: function (args) {
        if (this._updatePanelProgress === null)
            this._updatePanelProgress = $find(this._updatePanelProgressId);

        if (this._abortRequestHandlerDelegate === null && this._updatePanelProgress != null)
            this._updatePanelProgress.add_abortRequest(this._abortRequestHandlerDelegate);
        /*if it's a submit button then the form will submit, so try and use a non submit html element*/
        this._imgDesignerInitCallback();
        var h = this.get_events().getHandler('targetcontrolclick');
        if (h) h(this, args);
        return false;
    },
    _createImageDesigner: function (markup) {
        var container = document.createElement('div');
        var imageDesignerContent = Typps.Utility.getAdjacentHTML(markup, container).firstChild;
        this._imageDesignerAttributes = $get(this._imgDesignerId + '_attributes', imageDesignerContent);
        if (this._imageDesignerAttributes != null && !this._displayImageDesignerAttributes)
            this._imageDesignerAttributes.style.display = 'none';
        if (!this._displayImageDesignerUrlField) {
            var imageUrlCaption = $get(this._imgDesignerId + '_imageurlcaption', imageDesignerContent);
            var imageUrlField = $get(this._imgDesignerId + '_imageurlfield', imageDesignerContent);
            if (imageUrlCaption != null)
                imageUrlCaption.style.visibility = 'hidden';
            if (imageUrlField != null)
                imageUrlField.style.display = 'none';
        }
        this._imageDesignerWindow = this._createModalPopup(imageDesignerContent, this._imgDesignerId, false);
        var btnBrowse = $get(this._imgDesignerId + '_btnbrowse');

        if (this._imageBrowserEnabled) {
            if (this._btnBrowseDelegate === null)
                this._btnBrowseDelegate = Function.createDelegate(this, this._btnBrowseHandler);
        }
        else {
            btnBrowse.style.display = 'none';
        }
        if (this._imageUploadEnabled) {
            if (this._btnImgUploadDelegate === null)
                this._btnImgUploadDelegate = Function.createDelegate(this, this._btnImgUploadHandler);
        }
        else {
            $get(this._imgDesignerId + '_btnimgupload').style.display = 'none';
        }
        if (this._okButtonDelegate === null)
            this._okButtonDelegate = Function.createDelegate(this, this._okButtonHandler);

        if (this._cancelButtonDelegate === null)
            this._cancelButtonDelegate = Function.createDelegate(this, this._cancelButtonHandler);

        if (this._btnBrowseDelegate !== null)
            Sys.UI.DomEvent.addHandler(btnBrowse, 'click', this._btnBrowseDelegate);

        if (this._btnImgUploadDelegate !== null)
            Sys.UI.DomEvent.addHandler($get(this._imgDesignerId + '_btnimgupload'), 'click', this._btnImgUploadDelegate);
        this._imageDesignerWindow.add_okButton(this._okButtonDelegate);
        this._imageDesignerWindow.add_cancelButton(this._cancelButtonDelegate);
        this._imageDesignerWindow.add_popupCloseButton(this._cancelButtonDelegate);
        if (this._targetImage != null)
            this._setImagePropertiesEditMode();
    },
    _okButtonHandler: function (args) {
        var h = this.get_events().getHandler('ok');
        var argument = this._getImageDesignerFields();
        var image = this._createImageElement(argument);

        argument.set_image(image);
        var postbackElement = $get(this.get_id() + '_properties');
        if (this._targetImage != null) {
            this._targetImage = null;
            argument.set_isNew(false);
        }
        if (postbackElement != null)
            postbackElement.value = this._serializeEventArgs(argument);

        this._ensureTargetImage();

        if (h) h(this, argument);
        this._reset();
    },
    _serializeEventArgs: function (eventArgs) {
        var sb = new Sys.StringBuilder();
        sb.append(String.format('{0}:{1};', 'src', eventArgs.get_commandArgument()));
        sb.append(String.format('{0}:{1};', 'alt', eventArgs.get_alt()));
        sb.append(String.format('{0}:{1};', 'width', eventArgs.get_width()));
        sb.append(String.format('{0}:{1};', 'height', eventArgs.get_height()));
        sb.append(String.format('{0}:{1};', 'align', eventArgs.get_align()));
        sb.append(String.format('{0}:{1};', 'border', eventArgs.get_border()));
        sb.append(String.format('{0}:{1};', 'margin', eventArgs.get_margin()));
        sb.append(String.format('{0}:{1};', 'padding', eventArgs.get_padding()));
        return sb.toString();
    },
    _cancelButtonHandler: function (args) {
        var eventArgs = new Typps.ImageDesignerEventArgs();
        if (this._targetImage != null) {
            eventArgs.set_isNew(false);
            eventArgs.set_image(this._targetImage);
            this._targetImage = null;
        }
        this._ensureTargetImage();

        var h = this.get_events().getHandler('cancel');
        if (h) h(this, eventArgs);
        this._reset();
    },
    _reset: function () {
        var id = this._imgDesignerId;
        var src = $get(id + '_imgurl');
        var alt = $get(id + '_alt');
        var width = $get(id + '_width');
        var height = $get(id + '_height');
        var align = $get(id + '_align');
        var border = $get(id + '_border');
        var margin = $get(id + '_margin');
        var padding = $get(id + '_padding');
        if (src != null)
            src.value = 'http://';
        if (alt != null)
            alt.value = '';
        if (width != null)
            width.value = '';
        if (height != null)
            height.value = '';
        if (align != null)
            align.options[0].selected = true;
        if (border != null)
            border.value = 0;
        if (margin != null)
            margin.value = '';
        if (padding != null)
            padding.value = '';
        var thumbnail = $get(this._imgBrowserId + '_preview_img');
        if (thumbnail != null)
            thumbnail.style.visibility = 'hidden';
    },
    _getImageDesignerFields: function () {
        var id = this._imgDesignerId;
        var src = $get(id + '_imgurl');
        var alt = $get(id + '_alt');
        var width = $get(id + '_width');
        var height = $get(id + '_height');
        var align = $get(id + '_align');
        var border = $get(id + '_border');
        var margin = $get(id + '_margin');
        var padding = $get(id + '_padding');
        var eventArgs = new Typps.ImageDesignerEventArgs();
        eventArgs.set_commandArgument(src.value);
        eventArgs.set_alt(alt.value);
        eventArgs.set_width((isNaN(parseInt(width.value))) ? 0 : parseInt(width.value));
        eventArgs.set_height((isNaN(parseInt(height.value))) ? 0 : parseInt(height.value));
        eventArgs.set_align(align.options[align.selectedIndex].value);
        eventArgs.set_border((isNaN(parseInt(border.value))) ? 0 : parseInt(border.value));
        eventArgs.set_margin((isNaN(parseInt(margin.value))) ? 0 : parseInt(margin.value));
        eventArgs.set_padding((isNaN(parseInt(padding.value))) ? 0 : parseInt(padding.value));

        this._reset();
        return eventArgs;
    },
    _setImagePropertiesEditMode: function () {
        var img = this._targetImage;
        var id = this._imgDesignerId;
        var src = $get(id + '_imgurl');
        var alt = $get(id + '_alt');
        var width = $get(id + '_width');
        var height = $get(id + '_height');
        var align = $get(id + '_align');
        var border = $get(id + '_border');
        var margin = $get(id + '_margin');
        var padding = $get(id + '_padding');
        var src1 = img.getAttribute('src', 2);
        var src2 = img.getAttribute('src2');
        if (src2 != null) {
            img.src = src2;
            src.value = src2;
        } else {
            src.value = src1;
        }
        alt.value = img.alt;
        width.value = (isNaN(parseInt(img.style.width))) ? '' : parseInt(img.style.width);
        height.value = (isNaN(parseInt(img.style.height))) ? '' : parseInt(img.style.height);
        border.value = (isNaN(parseInt(img.style.borderWidth))) ? '' : parseInt(img.style.borderWidth);
        margin.value = (isNaN(parseInt(img.style.marginLeft))) ? '' : parseInt(img.style.marginLeft);
        padding.value = (isNaN(parseInt(img.style.paddingLeft))) ? '' : parseInt(img.style.paddingLeft);
        var floatDirection = (this._isIE) ? img.style.styleFloat : img.style.cssFloat;
        var alignSelectedIndex = Typps.Utility.getIndexByNameFromOptions(floatDirection, align.options);
        if (alignSelectedIndex != -1)
            align.options[alignSelectedIndex].selected = true;
    },
    _createImageElement: function (properties) {
        var id = this._imgDesignerId;
        var align = $get(id + '_align');
        var alignSelectedIndex = 0;
        var src = properties.get_commandArgument();
        if (src == 'http://' || src == '') return null;
        /*when used within the context of the editor, we need to use the document of the iframe when creating elements,
        currently the editor passes it's document to this control*/
        var img = (this._targetImage == null) ? this._document.createElement('img') : this._targetImage;
        img.src = properties.get_commandArgument();
        img.alt = properties.get_alt();
        if (align != null)
            alignSelectedIndex = Typps.Utility.getIndexByNameFromOptions(properties.get_align(), align.options);
        if (properties.get_border() != '')
            img.style.borderWidth = properties.get_border() + 'px';
        else
            img.style.borderWidth = '';
        if (alignSelectedIndex != 0)
            Typps.Utility.setFloat(img, properties.get_align());
        else
            Typps.Utility.setFloat(img, '');
        if (properties.get_width() > 0)
            img.style.width = properties.get_width() + 'px';
        else
            img.style.width = '';
        if (properties.get_height() > 0)
            img.style.height = properties.get_height() + 'px';
        else
            img.style.height = '';
        if (properties.get_margin() > 0)
            img.style.margin = properties.get_margin() + 'px';
        else
            img.style.margin = '';
        if (properties.get_padding() > 0)
            img.style.padding = properties.get_padding() + 'px';
        else
            img.style.padding = '';
        return img;
    },
    show: function (val) {
        if (this._targetImage != null)
            this._setImagePropertiesEditMode();
        this._imageDesignerWindow.show(val);
    },
    _show: function (val, img) {
        if (img != null) {
            this._targetImage = img;
            this._setImagePropertiesEditMode();
        }
        this._imageDesignerWindow.show(val);
    },
    refreshImageBrowserWindow: function () {
        if (this._imageBrowserWindow != null) {
            if (this._btnImgBrowserOkDelegate)
                delete this._btnImgBrowserOkDelegate;
            if (this._btnImgBrowserCancelDelegate)
                delete this._btnImgBrowserCancelDelegate;

            this._btnImgBrowserOkDelegate = null;
            this._btnImgBrowserCancelDelegate = null;

            this._disposeTreeView();

            this._imageBrowserWindow.dispose();
            delete this._imageBrowserWindow;

            if (this._mediaFrame != null) {
                this._mediaFrame.clearMediaItems();
                if (this._thumbnailClickDelegate) {
                    this._mediaFrame.remove_targetControlClick(this._thumbnailClickDelegate);
                    delete this._thumbnailClickDelegate;
                    this._thumbnailClickDelegate = null;
                }
            }
        }
    },
    _btnImgUploaderOkHandler: function (args) {
        //refresh imageBrowser (since we are adding a new image).
        this.refreshImageBrowserWindow();
        var file1 = $get(this._imgUploaderId + '_input');
        if (file1.value == '')
            return;

        var iframe = this._getIframe();

        if (this._iframeImageUploadDelegate === null) {
            this._iframeImageUploadDelegate = Function.createDelegate(this, this._iframeImageUploadHandler);
            Sys.UI.DomEvent.addHandler(iframe, 'load', this._iframeImageUploadDelegate);
        }
        var target = this._form.target;
        this._form.target = iframe.name;
        this._form.__EVENTTARGET.value = this._imgUploaderId;
        this._form.__EVENTARGUMENT.value = Sys.Serialization.JavaScriptSerializer.serialize({ id: file1.name, clientSidePath: file1.value });

        var eventArgs = new Typps.EventArgs();
        eventArgs.set_commandArgument(this._imageUploadingMessage);

        if (this._updatePanelProgress === null)
            this._updatePanelProgress = $find(this._updatePanelProgressId);

        this._updatePanelProgress.set_loadingMessage(this._imageUploadingMessage);
        this._updatePanelProgress.showProgressBar();

        this._beginRequestHandler(this, eventArgs);

        this._form.submit();
        this._form.target = target;
        this._form.__EVENTTARGET.value = '';
        this._form.__EVENTARGUMENT.value = '';
    },
    _getIframe: function () {
        var id = this._imgUploaderId + '_frame';
        var iframe = $get(id);
        if (iframe != null) return iframe;
        var ieBelow9 = this._isIE && Sys.Browser.version < 9;
        if (ieBelow9) {
            iframe = document.createElement(String.format('<iframe name="{0}">', id));
        }
        else {
            iframe = document.createElement('iframe');
            iframe.name = id;
        }
        iframe.id = id;
        iframe.style.display = 'none';
        this._form.appendChild(iframe);
        return iframe;
    },
    _iframeImageUploadHandler: function (args) {
        if (this._updatePanelProgress !== null)
            this._updatePanelProgress.hideProgressBar();
        var response = Sys.Serialization.JavaScriptSerializer.deserialize(args.target.contentWindow.document.body.firstChild.innerHTML);
        //we expect the message returned from the server(messageFromServer) to return the freshly saved
        //url when the image picker is within the context
        //of the html editor
        var url = response.messageFromServer;
        if (!this._displayImageDesignerUrlField) {
            var h = this.get_events().getHandler('ok');
            var arg = new Typps.EventArgs();
            arg.set_commandArgument(url);
            if (h) h(this, arg);
        }
        else if (!Typps.Utility.isNullOrEmpty(url)) {
            var field = $get(this._imgDesignerId + '_imgurl');
            if (field != null)
                field.value = url;
        }
    },
    _btnImgUploaderCancelHandler: function (args) {
        if (!this._displayImageDesignerUrlField) {
            var h = this.get_events().getHandler('cancel');
            if (h) h(this, args);
        }
    },

    _createImageBrowser: function (markup) {
        var container = document.createElement('div');
        var content = Typps.Utility.getAdjacentHTML(markup, container).firstChild;
        var isIE6 = (this._isIE && Sys.Browser.version <= 6);
        this._imageBrowserWindow = this._createModalPopup(content, this._imgBrowserId, false);
        if (this._btnImgBrowserOkDelegate === null) {
            this._btnImgBrowserOkDelegate = Function.createDelegate(this, this._btnImgBrowserOkHandler);
        }
        if (this._btnImgBrowserCancelDelegate === null) {
            this._btnImgBrowserCancelDelegate = Function.createDelegate(this, this._btnImgBrowserCancelHandler);
        }

        this._imageBrowserWindow.add_okButton(this._btnImgBrowserOkDelegate);
        this._imageBrowserWindow.add_cancelButton(this._btnImgBrowserCancelDelegate);
        this._imageBrowserWindow.add_popupCloseButton(this._btnImgBrowserCancelDelegate);
        this._loadingStatus = $get(this._imgBrowserId + '_loadingstatus');
        if (this._loadingStatus != null)
            this._loadingStatus.style.visibility = 'hidden';

        if (this._thumbnailClickDelegate === null)
            this._thumbnailClickDelegate = Function.createDelegate(this, this._thumbnailClickHandler);
        if (this._onMediaFrameCloseDelegate === null)
            this._onMediaFrameCloseDelegate = Function.createDelegate(this, this._onMediaFrameCloseHandler);
        if (this._onMediaItemDisplayDelegate === null)
            this._onMediaItemDisplayDelegate = Function.createDelegate(this, this._onMediaFrameCloseHandler);
        if (!isIE6 && (this._mediaFrame === null && this._mediaFrameId != '')) {
            this._mediaFrame = $find(this._mediaFrameId);
            this._mediaFrame.add_targetControlClick(this._thumbnailClickDelegate);
            var h = this._mediaFrame.get_events().getHandler('onmediaitemdisplay');
            if (h == null)
                this._mediaFrame.add_closeButton(this._onMediaFrameCloseDelegate);
            else
                this._mediaFrame.add_onMediaItemDisplay(this._onMediaItemDisplayDelegate);
        }
        var previewContainer = $get(this._imgBrowserId + '_preview');

        var thumbnail = document.createElement('img');
        var size = this._thumbnailWidth;
        thumbnail.style.width = size + 'px';
        thumbnail.style.height = size + 'px';
        thumbnail.id = this._imgBrowserId + '_preview_img';
        if (this._mediaFrame !== null)
            thumbnail.style.cursor = 'pointer';
        thumbnail.style.visibility = 'hidden';
        if (this._thumbnailLoadedDelegate === null)
            this._thumbnailLoadedDelegate = Function.createDelegate(this, this._thumbnailLoadedHandler);
        Sys.UI.DomEvent.addHandler(thumbnail, 'load', this._thumbnailLoadedDelegate);

        var context = this;
        if (this._thumbnailOnErrorDelegate === null)
            this._thumbnailOnErrorDelegate = Function.createCallback(context._thumbnailOnErrorHandler, context);
        thumbnail.onerror = this._thumbnailOnErrorDelegate;

        previewContainer.appendChild(thumbnail);

        var treeview = $get(this.get_id() + '_treeview');
        var classNames1 = { a: 'nodecollapse', b: 'nodeexpand', c: 'clickablenonlink' };
        var classNames2 = { a: 'nonlink' };
        this._getElementsByClassName(treeview, 'span', classNames1, this._rootElements);
        this._getElementsByClassName(treeview, 'b', classNames1, this._rootElements);
        this._getElementsByClassName(treeview, 'span', classNames2, this._leafElements);
        var num1;
        for (num1 = 0; num1 < this._rootElements.length; num1++) {
            var spanRoot = this._rootElements[num1];
            if (this._toggleTreeViewStateDelegate === null) {
                this._toggleTreeViewStateDelegate = Function.createDelegate(this, this._toggleTreeViewStateHandler);
            }
            Sys.UI.DomEvent.addHandler(spanRoot, 'click', this._toggleTreeViewStateDelegate);
        }
        if (this._leafElements.length > 0 && this._leafNodeClickDelegate === null)
            this._leafNodeClickDelegate = Function.createDelegate(this, this._leafNodeClickHandler);

        var sb = null;
        if (this._mediaFrame != null && this._leafElements.length > 0)
            sb = new Sys.StringBuilder();
        for (num1 = 0; num1 < this._leafElements.length; num1++) {
            var spanLeaf = this._leafElements[num1];
            Sys.UI.DomEvent.addHandler(spanLeaf, 'click', this._leafNodeClickDelegate);
            if (sb != null && !isIE6) {
                var text = this._getElementByLocation(spanLeaf, 'span', 0).innerHTML;
                var url = this._getElementByLocation(spanLeaf, 'b', 0).innerHTML;
                sb.append(String.format('{{"url":"{0}","title":"{1}","value":"{2}"}}', url, spanLeaf.title, url));
            }
        }
        if (this._mediaFrame != null && sb != null) {
            this._mediaFrame.set_targetControlId(thumbnail.id);
            var json = String.format('[{0}]', sb.toString(','));
            var mediaFrameItems = Sys.Serialization.JavaScriptSerializer.deserialize(json);
            this._mediaFrame.set_mediaItems(mediaFrameItems);
            this._mediaFrame.initializeMediaFrame();
        }
    },
    _selectLeftNodeByUrl: function (value) {
        var spanLeaf = null;
        var flag1 = false;
        for (num1 = 0; num1 < this._leafElements.length; num1++) {
            spanLeaf = this._leafElements[num1];
            var url = this._getElementByLocation(spanLeaf, 'b', 0).innerHTML;
            if (url == value) {
                flag1 = true;
                break;
            }
        }
        if (flag1) {
            var selectedClass = 'nodeselected';
            this._removeClassFromAllLeafNodes(selectedClass);
            this._addCssClass(spanLeaf, selectedClass);
        }
    },
    _leafNodeClickHandler: function (args) {
        var container = args.target.parentNode;
        var previewContainer = $get(this._imgBrowserId + '_preview');
        var thumbnail = $get(this._imgBrowserId + '_preview_img');
        var text = this._getElementByLocation(container, 'span', 0).innerHTML;
        var url = this._getElementByLocation(container, 'b', 0).innerHTML;
        thumbnail.style.visibility = 'hidden';
        this._loadingStatus.style.visibility = 'visible';
        thumbnail.setAttribute('value', url);
        thumbnail.src = this._httpHandlerUrl + encodeURI(url);
        thumbnail.alt = text;

        var selectedClass = 'nodeselected';
        this._removeClassFromAllLeafNodes(selectedClass);
        this._addCssClass(container, selectedClass);
    },
    _removeClassFromAllLeafNodes: function (className) {
        for (var num1 = 0; num1 < this._leafElements.length; num1++) {
            var leafNode = this._leafElements[num1];
            this._removeCssClass(leafNode, className);
        }
    },
    _thumbnailLoadedHandler: function (args) {
        var elem = args.target;
        elem.style.visibility = 'visible';
        this._loadingStatus.style.visibility = 'hidden';
        var h = this.get_events().getHandler('thumbnailloaded');
        if (h) h(this, args);
    },
    _thumbnailClickHandler: function (sender, args) {
        var elem = args.target;
        var originalUrl = elem.getAttribute('value');
        var h = this.get_events().getHandler('thumbnailclicked');
        if (h) h(this, args);
    },
    _thumbnailOnErrorHandler: function (args1, args2) {
        /*ie does not pass the event, so lets workaround!*/
        var context = null;
        var args = null;
        if (args2 == null) {
            args = window.event;
            context = args1;
        }
        else {
            args = args1;
            context = args2;
        }
        var elem = (context._isIE) ? args.srcElement : args.target;
        elem.style.visibility = 'hidden';
        elem.src = context._loadFailureUrl;
        context._loadingStatus.style.visibility = 'visible';
        var h = context.get_events().getHandler('thumbnailloaded');
        if (h) h(context, args);
    },
    _onMediaFrameCloseHandler: function (sender, args) {
        var value = args.get_commandName();
        var url = args.get_commandArgument();
        var thumbnail = $get(this._imgBrowserId + '_preview_img');
        thumbnail.setAttribute('value', value);
        thumbnail.src = this._httpHandlerUrl + encodeURI(url);
        this._selectLeftNodeByUrl(url);
    },
    _toggleTreeViewStateHandler: function (args) {
        // args.target returns the node on which our mouse pointer clicked
        // this is not necessarily the node on whom we attached the click event
        // but a child node whose event bubbled up. Here we identify a childnode
        // whose event bubbled by checking className. The childnodes do not have
        // a class name so this is a good marker in this particular situation!
        var parentNode = null;
        if (args.target.className == '')
            parentNode = args.target.parentNode.parentNode;
        else
            parentNode = args.target.parentNode;
        var leafNodes = parentNode.getElementsByTagName('ul');
        var stateNode = this._getElementByLocation(parentNode, 'b', 0);
        this._toggleCssClass(leafNodes[0], 'nodehide');
        if (stateNode == null)
            return;
        var containsClass = Typps.Utility.containsCssClass(stateNode, 'nodeexpand');
        if (containsClass)
            stateNode.className = 'nodecollapse';
        else
            stateNode.className = 'nodeexpand';
    },
    _getElementByLocation: function (element, tagName, index) {
        var location = 0;
        for (var num1 = 0; num1 < element.childNodes.length; num1++) {
            var elm = element.childNodes[num1];
            if (elm.nodeName.toLowerCase() == tagName.toLowerCase()) {
                if (location == index)
                    return elm;
                else
                    location++;
            }
        }
        return null;
    },
    _getElementsByClassName: function (element, tagName, className, collection) {
        if (element == null)
            return [];
        var elems = element.getElementsByTagName(tagName);
        for (var num1 = 0; num1 < elems.length; num1++) {
            var elm = elems[num1];
            var containsClass = false;
            for (var s in className) {
                containsClass = Typps.Utility.containsCssClass(elm, className[s]);
                if (containsClass) {
                    collection[collection.length] = elm;
                    break;
                }
            }
        }
        return collection;
    },
    _btnImgBrowserOkHandler: function (args) {
        var thumbnail = $get(this._imgBrowserId + '_preview_img');
        var urlInput = $get(this._imgDesignerId + '_imgurl');
        var originalUrl = thumbnail.getAttribute('value');
        if (originalUrl != null) {
            var url = originalUrl.replace(new RegExp(this._authority, 'i'), '');
            if (!this._displayImageDesignerUrlField) {
                var h = this.get_events().getHandler('ok');
                var postbackArgument = new Typps.ImageDesignerEventArgs();
                postbackArgument.set_commandArgument(url);
                var image = this._createImageElement(postbackArgument);

                postbackArgument.set_image(image);
                var postbackElement = $get(this.get_id() + '_properties');
                if (this._targetImage != null) {
                    this._targetImage = null;
                    postbackArgument.set_isNew(false);
                }

                if (postbackElement != null)
                    postbackElement.value = this._serializeEventArgs(postbackArgument);

                this._ensureTargetImage();

                var argument = new Typps.EventArgs();
                argument.set_commandArgument(url);
                if (h) h(this, argument);
                this._reset();
            }
            else if (urlInput != null) {
                urlInput.value = url;
            }
        }
        var selectedClass = 'nodeselected';
        this._removeClassFromAllLeafNodes(selectedClass);
    },
    _btnImgBrowserCancelHandler: function (args) {
        var thumbnail = $get(this._imgBrowserId + '_preview_img');
        if (thumbnail != null)
            thumbnail.style.visibility = 'hidden';
        var selectedClass = 'nodeselected';
        this._removeClassFromAllLeafNodes(selectedClass);
        if (!this._displayImageDesignerUrlField) {
            var h = this.get_events().getHandler('cancel');
            if (h) h(this, args);
        }
    },
    _imgDesignerInitCallback: function () {
        var argument = Typps.Utility.getCommandArgument('insertimage', this.get_callbacks());
        var formKeyValuePair = { formdata: argument.commandArgument };
        if ((!this._imageUploadEnabled && !this._displayImageDesignerAttributes) && !this._displayImageDesignerUrlField) {
            this._btnBrowseHandler(null);
        }
        else if ((this._imageUploadEnabled && !this._displayImageDesignerAttributes) && (!this._displayImageDesignerUrlField && !this._imageBrowserEnabled)) {
            this._btnImgUploadHandler(null);
        }
        else {
            if (this._imageDesignerWindow == null)
                this._fireUpdatePanelTrigger(formKeyValuePair, argument.commandArgument, argument.message);
            else
                this.show(true);
        }
    },
    _btnBrowseHandler: function (args) {
        var argument = Typps.Utility.getCommandArgument('imagebrowser', this.get_callbacks());
        var formKeyValuePair = { formdata: argument.commandArgument };
        if (this._imageBrowserWindow == null)
            this._fireUpdatePanelTrigger(formKeyValuePair, argument.commandArgument, argument.message);
        else
            this._imageBrowserWindow.show(true);
    },
    _btnImgUploadHandler: function (args) {
        var argument = Typps.Utility.getCommandArgument('imageupload', this.get_callbacks());
        var formKeyValuePair = { formdata: argument.commandArgument };
        if (this._imageUploaderWindow == null)
            this._fireUpdatePanelTrigger(formKeyValuePair, argument.commandArgument, argument.message);
        else
            this._imageUploaderWindow.show(true);
    },

    _beginRequestHandler: function (sender, args) {
        var h = this.get_events().getHandler('beginWebRequest');
        if (h) h(this, args);
    },
    _endRequestHandler: function (sender, args) {
        var h = this.get_events().getHandler('endWebRequest');
        if (!sender.get_responseAvailable()) {
            if (h) h(this, args);
            return;
        }
        var eventArgs = new Typps.EventArgs();
        var parts = sender.get_responseData().split(String.format('$callbackdata${0}$sep$', this.get_id()));
        var key = parts[0];
        var value = parts[1];
        eventArgs.set_commandName(key);
        eventArgs.set_commandArgument(value);
        eventArgs.set_innerArgs(args);
        if (h) h(this, eventArgs);

        switch (key) {
            case 'ImageUploadRequest':
                this._createImageUploader(value);
                break;
            case 'ImageBrowserRequest':
                this._createImageBrowser(value);
                break;
            case 'ImageDesignerRequest':
                this._createImageDesigner(value);
                break;
        }
    },

    _makeWebRequest: function (eventArgs, formKeyValuePair) {
        var pageManager = Sys.WebForms.PageRequestManager.getInstance();
        var formBody = Typps.Utility.getFormKeyValuePair(this._uniqueId, formKeyValuePair, this._form, true);
        var request = new Sys.Net.WebRequest();
        request.set_url(this._form.action);
        request.get_headers()['X-MicrosoftAjax'] = 'Delta=true';
        request.get_headers()['Cache-Control'] = 'no-cache';
        request.set_timeout(pageManager._asyncPostBackTimeout);
        request.set_body(formBody);
        if (this._updatePanelProgress === null)
            this._updatePanelProgress = $find(this._updatePanelProgressId);
        if (this._updatePanelProgress === null) return;

        this._updatePanelProgress.set_loadingMessage(eventArgs.get_commandArgument());
        if (this._beginRequestHandlerDelegate == null) {
            this._beginRequestHandlerDelegate = Function.createDelegate(this, this._beginRequestHandler);
            this._updatePanelProgress.add_beginRequest(this._beginRequestHandlerDelegate);
        }
        if (this._endRequestHandlerDelegate == null) {
            this._endRequestHandlerDelegate = Function.createDelegate(this, this._endRequestHandler);
            this._updatePanelProgress.add_endRequest(this._endRequestHandlerDelegate);
        }
        this._updatePanelProgress._makeWebRequest(request);
    },
    _fireUpdatePanelTrigger: function (formKeyValuePair, commandName, message) {
        var eventArgs = new Typps.EventArgs();
        eventArgs.set_commandName(commandName);
        eventArgs.set_commandArgument(message);
        this._makeWebRequest(eventArgs, formKeyValuePair);
    },
    _toggleCssClass: function (elem, className) {
        Typps.Utility.addRemoveClassName(elem, className, Typps.Perform.Toggle);
    },
    _addCssClass: function (elem, className) {
        Typps.Utility.addRemoveClassName(elem, className, Typps.Perform.Add);
    },
    _removeCssClass: function (elem, className) {
        Typps.Utility.addRemoveClassName(elem, className, Typps.Perform.Remove);
    }
}
Typps.ImagePicker.registerClass('Typps.ImagePicker', Sys.UI.Control);

Typps.ImageDesignerEventArgs = function () {
    Typps.ImageDesignerEventArgs.initializeBase(this);
    this._alt = '';
    this._width = 0;
    this._height = 0;
    this._align = null;
    this._border = 0;
    this._margin = 0;
    this._padding = 0;
    this._image = null;
    this._isNew = true;
}
Typps.ImageDesignerEventArgs.prototype = {
    get_alt: function () { return this._alt; },
    set_alt: function (value) { this._alt = value; },
    get_width: function () { return this._width; },
    set_width: function (value) { this._width = value; },
    get_height: function () { return this._height; },
    set_height: function (value) { this._height = value; },
    get_align: function () { return this._align; },
    set_align: function (value) { this._align = value; },
    get_border: function () { return this._border; },
    set_border: function (value) { this._border = value; },
    get_margin: function () { return this._margin; },
    set_margin: function (value) { this._margin = value; },
    get_padding: function () { return this._padding; },
    set_padding: function (value) { this._padding = value; },
    get_image: function () { return this._image; },
    set_image: function (value) { this._image = value; },
    get_isNew: function () { return this._isNew; },
    set_isNew: function (value) { this._isNew = value; }
}
Typps.ImageDesignerEventArgs.registerClass('Typps.ImageDesignerEventArgs', Typps.EventArgs);

// Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
// invoke Sys.Application.notifyScriptLoaded to notify ScriptManager 
// that this is the end of the script.
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

